#ifndef XGE_GRAPHICS_WINDOW_H_
#define XGE_GRAPHICS_WINDOW_H_
#include "xge_common_config.h"
#include "g_rendertarget.h"
#include "xstring.h"
#include "xsmart_ptr.h"

namespace xge{
namespace graphics{
  class Graphics2D;
}
namespace window{
  // Create a graphics window 
  using xge_internal::IntrinsicPointer;

  class FocusChangeListener : public IntrinsicPointer<FocusChangeListener> {
  public:
    virtual void OnFocusGain() =0;
    virtual void OnFocusLost() =0;
    virtual ~FocusChangeListener() {}
  };

  class OnExitListener : public IntrinsicPointer< OnExitListener > {
  public:
    virtual void OnExit() =0;
    virtual ~OnExitListener() {}
  };

  class GraphicsWindow {
  public: // Functional stuff 
    // Snapshot the window and save the content into
    // the file ( path specified by the file_path )
    virtual bool Snapshot( const String& file_path ) = 0;
  public:
    // is this window fullscreen or not
    bool fullscreen() const {
      return fullscreen_;
    }
    // get the height and width of this window
    size_t width() const {
      return width_;
    }
    // get the height of this window
    size_t height() const {
      return height_;
    }
    // get the caption of this window
    const String& caption () const {
      return caption_;
    }
    // set the caption of this window
    void set_caption( const String& caption ) {
      caption_ = caption ;
      NotifyCaptionName( caption.c_str() );
    }
    // set the OnExitListener
    void set_on_exit_listener( OnExitListener* listener ) {
      if( on_exit_listener_ )
        on_exit_listener_->Drop();
      if( listener )
        listener->Grab();
      on_exit_listener_ = listener;
      
    }
    void set_focus_change_listener( FocusChangeListener* listener ) {
      if( focus_change_listener_ )
        focus_change_listener_->Drop();
      if( listener )
        listener->Grab();
      focus_change_listener_ = listener;
    }
  public:
    // Get the platform related handler 
    virtual void GetPlatformHandler( void** out_argument ) = 0;
    // The dtor should destroy the listener 
    virtual ~GraphicsWindow() {
      if( focus_change_listener_ )
        focus_change_listener_->Drop();
      if( on_exit_listener_ )
        on_exit_listener_->Drop();
    }
  protected:
    // Since this window should only be derived , so 
    // simply use the default CTor is ok !
    GraphicsWindow()
      :on_exit_listener_(NULL),focus_change_listener_(NULL){}
    // Notify the upper class to change the caption of this
    // window
    virtual void NotifyCaptionName( const char_t* caption ) = 0;
  protected:
    void set_width( size_t width ) {
      width_ = width;
    }
    void set_height( size_t height ) {
      height_ = height;
    }
    void set_fullscreen( bool fullscreen ) {
      fullscreen_ = fullscreen;
    }
  private:
    String caption_;
    size_t width_ , height_;
    bool fullscreen_;
  protected:
    OnExitListener* on_exit_listener_;
    FocusChangeListener* focus_change_listener_;
  };

}// namespace windows
}// namespace xge



#endif// XGE_GRAPHICS_G_WINDOW_H_